package org.lab.tracecash.web.rest.impl;

import java.util.ArrayList;
import java.util.List;

import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;

import org.lab.tracecash.common.model.SearchParams;
import org.lab.tracecash.common.model.SearchResults;
import org.lab.tracecash.model.Account;
import org.lab.tracecash.model.Transaction;
import org.lab.tracecash.services.AccountService;
import org.lab.tracecash.web.model.AccountMenuDetail;
import org.lab.tracecash.web.rest.AbstractRestEntityService;

@Path("/account")
@Consumes({ "application/json; charset=UTF-8" })
@Produces({ "application/json; charset=UTF-8" })
public class AccountRestService extends AbstractRestEntityService<Account> {

	@Inject
	private AccountService accountService;

	@GET
	@Path("/find")
	public SearchResults<Account> find(@QueryParam("q") String queryString, @QueryParam("p") Long page, @QueryParam("n") Integer pageSize) {
		SearchParams searchParams = new SearchParams().withQueryString(queryString).withCurrentPage(page).withPageSize(pageSize);
		return find(searchParams);
	}

	@GET
	@Produces("application/json")
	@Path("/id/{id}")
	public Account findById(@PathParam("id") Long id) {
		return accountService.findById(id);
	}

	// @GET
	// @Produces("application/json")
	// @Path("/find/user/{id}")
	// public List<Account> findByUser(@PathParam("id") Long id, @QueryParam("exp") String exp) {
	// EntityManager entityManager = entityManagerProvider.get();
	// CriteriaBuilder builder = entityManager.getCriteriaBuilder();
	// CriteriaQuery<Account> criteria = builder.createQuery(Account.class);
	// Root<Account> root = criteria.from(Account.class);
	// criteria.multiselect(root.<Long> get("id"), root.<String> get("name"));
	// List<Predicate> predicates = new ArrayList<Predicate>();
	// predicates.add(builder.equal(root.<User> get("owner").<Long> get("id"), id));
	// if (StringUtils.isNotBlank(exp)) {
	// predicates.add(builder.like(root.<String> get("name"), exp + "%"));
	// }
	// criteria.where(predicates.toArray(new Predicate[predicates.size()]));
	// criteria.orderBy(builder.asc(root.<String> get("name")));
	// return entityManager.createQuery(criteria).getResultList();
	// }

	// TODO PASARLO A JPA!
	@GET
	@Produces("application/json")
	@Path("/find/user/detail/{id}")
	@SuppressWarnings("unchecked")
	public List<AccountMenuDetail> findDetail(@PathParam("id") Long userId) {
		EntityManager entityManager = entityManagerProvider.get();
		String sql = "select a.id, a.name, count(a.name) from tc_transaction t join tc_account a on (t.ac_from= a.id or t.ac_to = a.id) join tc_user u where u.id = " + userId
				+ " group by a.id, a.name order by a.name";
		List<Object[]> list = entityManager.createNativeQuery(sql).getResultList();
		List<AccountMenuDetail> result = new ArrayList<AccountMenuDetail>();
		for (Object[] i : list) {
			result.add(new AccountMenuDetail((Long) i[0], (String) i[1], (Long) i[2]));
		}
		return result;
	}

	@GET
	@Produces("application/json")
	@Path("/name/{name}")
	public Account getByName(@PathParam("id") String name, @PathParam("owner") Long ownerId) {
		return accountService.getByName(name, ownerId);
	}

	@GET
	@Produces("application/json")
	@Path("/operations/{id}")
	public List<Transaction> getPortfolioOperations(@PathParam("id") Long id) {
		return accountService.getTransactions(id);
	}

	@Override
	protected Class<Account> getEntityClass() {
		return Account.class;
	}
}
